home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
text
/
misc
/
pcal_4_5.lha
/
pcal
/
pcalinit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-16
|
7KB
|
273 lines
/*
* Create a .h file from a .ps file. Strips out leading and trailing
* whitespace, blank lines, and lines consisting solely of comments,
* except for the very first block of comments/blanklines, which are
* turned into C comments at the top of the file.
*
* 14-sep-90 Jamie Zawinski created.
*
* Revision history:
*
* 4.5 AWR 04/05/94 avoid adding block name comment if
* first line already contains comment
*
* 12/08/93 support #BEGIN <name>..#END blocks
* for optional sections of PostScript
* boilerplate (cf. writefil.c,
* pcalinit.ps)
*
* 09/09/93 propagate "%%" comments to output file
*
* 4.3 AWR 10/15/91 minor tweak to avoid redefinition
* of PROTOS
*
* 4.0 AWR 02/25/91 added optional third argument for
* name of array
*
* 02/19/91 added function prototypes; documented
*
* 01/16/91 Escape " and \ in quoted strings;
* strip trailing comments; skip FF
*
* 2.6 JAB 10/18/90 Add exit(0).
*
* 2.3 JWZ 09/14/90 Author
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifndef SEEK_SET /* symbolic definition for fseek() */
#define SEEK_SET 0
#endif
#if !defined(PROTOS) && (defined(__STDC__) || defined(AMIGA))
#define PROTOS
#endif
#define FALSE 0
#define TRUE 1
#define BEGIN_STR "#BEGIN" /* block delimiters */
#define END_STR "#END"
#define ARRAY_NAME "header" /* default name of array in .h file */
#define IS_WHITESPACE(c) \
((c) == ' ' || (c) == '\t' || (c) == '\n' || c == '\f')
#define IS_POSTSCRIPT(s) ((s)[0] != '%' && (s)[0] != '\0')
#define IS_PSCOMMENT(s) ((s)[0] == '%' && (s)[1] == '%')
#define IS_BEGIN(s) (strstr((s), BEGIN_STR) == (s))
#define IS_END(s) (strstr((s), END_STR) == (s))
/*
* strip_white: strip leading and trailing whitespace from 'string'; return
* pointer to first non-whitespace character
*/
char *
#ifdef PROTOS
strip_white(char *string)
#else
strip_white(string)
char *string;
#endif
{
int n;
for (; IS_WHITESPACE(*string); string++)
;
n = strlen(string)-1;
for (; IS_WHITESPACE(string[n]); n--)
string[n] = '\0';
return string;
}
/*
* strip_comment: strip comment (unless denoted by "%%") and any preceding
* whitespace from 'string'; return pointer to 'string'
*/
char *
#ifdef PROTOS
strip_comment(char *string)
#else
strip_comment(string)
char *string;
#endif
{
char *p;
if ((p = strchr(string, '%')) != NULL) {
if (p[1] == '%') /* propagate '%%' comments */
do
p[0] = p[1]; /* squeeze out initial '%' */
while (*++p);
else
*p = '\0'; /* delete '%' comments */
string = strip_white(string);
}
return string;
}
/*
* escape: copy string 'in' to string 'out', escaping the characters \ and ";
* return pointer to 'out'
*/
char *
#ifdef PROTOS
escape(char *out,
char *in)
#else
escape(out, in)
char *out, *in;
#endif
{
char c, *sv_out = out;
for (; c = *in; *out++ = *in++)
if (c == '\\' || c == '"')
*out++ = '\\';
*out = '\0';
return sv_out;
}
int
#ifdef PROTOS
main(int argc,
char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
FILE *in, *out;
char line[256], line2[512], *L, *array, *p, blockname[80];
int in_initial_comments, in_block, lineno;
/* retrieve arguments and attempt to open input and output files */
if (argc < 3 || argc > 4) {
fprintf(stderr, "usage: %s <infile>.ps <outfile>.h [<arrayname>]\n",
argv[0]);
exit(-1); }
in = fopen(argv[1], "r");
if (NULL == in) {
fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[1]);
exit(-1); }
out = fopen(argv[2], "w");
if (NULL == out) {
fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[2]);
exit(-1); }
array = argc == 4 ? argv[3] : ARRAY_NAME;
/* print topline comment on output file */
fprintf (out, "/*\n * %s: automatically generated by %s from %s\n",
argv[2], argv[0], argv[1]);
fprintf (out, " *\n *\tDO NOT EDIT THIS FILE!\n *\n");
/*
* main loop - copy lines from input file, to output file, preserving
* only initial block of comments and blank lines and skipping
* over #BEGIN..#END blocks
*/
in_block = FALSE;
in_initial_comments = TRUE;
for (lineno = 1; fgets(line, 255, in) != NULL; lineno++ ) {
L = strip_white(line); /* strip whitespace */
if ( IS_POSTSCRIPT(L) || /* PostScript source or */
IS_PSCOMMENT(L) ) { /* comment to propagate? */
if ( in_initial_comments ) { /* first PS line? */
in_initial_comments = FALSE;
fprintf(out, " */\n\nchar *%s[] = {\n", array);
}
if (IS_PSCOMMENT(L))
L++; /* drop first % from %% */
else
L = strip_comment(L); /* strip trailing comment */
if (IS_BEGIN(L)) {
if (in_block) {
fprintf(stderr, "%s: #BEGIN nesting error in %s (line %d)\n",
argv[0], argv[1], lineno);
exit(-1);
}
in_block = TRUE;
}
else if (IS_END(L)) {
if (!in_block) {
fprintf(stderr, "%s: #END nesting error in %s (line %d)\n",
argv[0], argv[1], lineno);
exit(-1);
}
in_block = FALSE;
}
else if (!in_block) {
L = escape(line2, L);
fprintf(out, " \"%s\",\n", L);
}
} else
/* blank or comment line - copy only if in initial comment block */
if ( in_initial_comments )
fprintf(out, " * %s\n", L);
}
fprintf(out, " (char *)0,\n};\n"); /* terminate array decl */
if (in_block) { /* unterminated block? */
fprintf(stderr, "%s: unterminated #BEGIN..#END block in %s\n",
argv[0], argv[1]);
exit(-1);
}
/*
* second loop - copy only lines within #BEGIN .. #END blocks
*/
fseek(in, 0L, SEEK_SET); /* rewind */
in_block = FALSE;
blockname[0] = '\0';
while ( fgets(line, 255, in) != NULL ) {
L = strip_white(line); /* strip whitespace */
if ( IS_POSTSCRIPT(L) ) {
L = strip_comment(L); /* strip trailing comment */
if (IS_BEGIN(L)) {
in_block = TRUE;
for (p = L + strlen(BEGIN_STR); *p && IS_WHITESPACE(*p); p++)
;
fprintf(out, "\nchar *%s[] = {\n", p);
strcpy(blockname, p);
}
else if (IS_END(L)) {
fprintf(out, " (char *)0,\n};\n"); /* terminate array decl */
in_block = FALSE;
}
else if (in_block) {
/* copy PostScript to output file; add block name to first line */
L = escape(line2, L);
fprintf(out, " \"%s", L);
if (blockname[0] && !strchr(L, '%'))
fprintf(out, "\\t\\t\\t%% %s", blockname);
blockname[0] = '\0';
fprintf(out, "\",\n");
}
}
}
fclose(out); /* close files and exit */
fclose(in);
exit (0);
}